package com.carrie.config.handler;

import com.carrie.config.security.JwtRequestFilter;
import com.carrie.config.security.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.security.Key;

/**
 * @author XuHaiLong
 * @since 2025/4/13 20:52
 */
/**@Configuration //配置类 这样初始化的时候就会将Bean注入到上下文当中
//@EnableWebSecurity //开springSecurity的自定义配置 如果是Springboot项目可以省略
public class SecurityConfigbk {
    @Autowired
    JwtRequestFilter jwtRequestFilter;
    @Autowired
    UserDetailsService userDetailsService;
    //添加密码编码器 Bean
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
//    实现支持手动进行认证
    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
        AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManagerBuilder.userDetailsService(userDetailsService);
        return authenticationManagerBuilder.build();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(authorize -> authorize
                        // 允许 /authenticate 接口无需认证访问
                        .requestMatchers("/authenticate","/register","/home","/druid/*").permitAll()
                        .requestMatchers("/logout").authenticated()
                        .requestMatchers("/api/**").hasAuthority("API")
                        .anyRequest().authenticated()
                )
               .formLogin(form -> form
                       .loginPage("/login").permitAll()
                       .successHandler(new MyAuthenticationSuccessHandler())
                       .failureHandler(new MyAuthenticationFailureHandler())
               )
                .logout(logout -> logout
                        .logoutUrl("/logout") // 指定注销URL
                        .invalidateHttpSession(true) // 使session失效
                        .deleteCookies("JSESSIONID") // 删除cooki
                        .logoutSuccessHandler(new MyLoginoutSuccessHandler())
                )
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
                .sessionManagement(session ->session
                        .maximumSessions(2).expiredSessionStrategy(new MySessionInformationExpireStrategy()))
                .userDetailsService(userDetailsService)
                .exceptionHandling(exception->exception
                        .authenticationEntryPoint(new MyAuthenticationEntryPoint())
                        .accessDeniedHandler(new MyAccessDeniedHandler()))
                .csrf(csrf->csrf.ignoringRequestMatchers("/**"));
//                .oauth2ResourceServer(oauth2ResourceServer -> oauth2ResourceServer
//                        .jwt(jwt -> {
//                            jwt.decoder(jwtDecoder());
//                        })
//                )
        return http.build();
    }
    @Bean
    public JwtDecoder jwtDecoder() {
        Key signingKey = JwtUtils.getSigningKey();
        return NimbusJwtDecoder.withSecretKey((javax.crypto.SecretKey) signingKey).build();
    }

}
**/